using System.Collections.Generic;
using System.Linq;
using Cosmos.I18N.Core;
using EnumsNET;

namespace Cosmos.I18N.Countries.Europe
{
    /// <summary>
    /// Macedonia Regons
    /// </summary>
    public static partial class Macedonia
    {
        private static IEnumerable<EnumMember<EnumValues>> InternalEnumMembersCache { get; } = RegionEnumHelper.Cache<EnumValues>();

        private static Dictionary<long, EnumValues> InternalCrCodeMappingCache { get; } = RegionEnumHelper.Mapping(InternalEnumMembersCache);

        #region Region getter

        public static class Regions
        {
            /// <summary>
            /// Aračinovo
            /// </summary>
            public static EnumValues Aračinovo => EnumValues.Aračinovo;

            /// <summary>
            /// Berovo
            /// </summary>
            public static EnumValues Berovo => EnumValues.Berovo;

            /// <summary>
            /// Bitola
            /// </summary>
            public static EnumValues Bitola => EnumValues.Bitola;

            /// <summary>
            /// Bogdanci
            /// </summary>
            public static EnumValues Bogdanci => EnumValues.Bogdanci;

            /// <summary>
            /// Bogovinje
            /// </summary>
            public static EnumValues Bogovinje => EnumValues.Bogovinje;

            /// <summary>
            /// Bosilovo
            /// </summary>
            public static EnumValues Bosilovo => EnumValues.Bosilovo;

            /// <summary>
            /// Brvenica
            /// </summary>
            public static EnumValues Brvenica => EnumValues.Brvenica;

            /// <summary>
            /// Valandovo
            /// </summary>
            public static EnumValues Valandovo => EnumValues.Valandovo;

            /// <summary>
            /// Vasilevo
            /// </summary>
            public static EnumValues Vasilevo => EnumValues.Vasilevo;

            /// <summary>
            /// Vevčani
            /// </summary>
            public static EnumValues Vevčani => EnumValues.Vevčani;

            /// <summary>
            /// Veles
            /// </summary>
            public static EnumValues Veles => EnumValues.Veles;

            /// <summary>
            /// Vinica
            /// </summary>
            public static EnumValues Vinica => EnumValues.Vinica;

            /// <summary>
            /// Vrapčište
            /// </summary>
            public static EnumValues Vrapčište => EnumValues.Vrapčište;

            /// <summary>
            /// Gevgelija
            /// </summary>
            public static EnumValues Gevgelija => EnumValues.Gevgelija;

            /// <summary>
            /// Gostivar
            /// </summary>
            public static EnumValues Gostivar => EnumValues.Gostivar;

            /// <summary>
            /// Gradsko 
            /// </summary>
            public static EnumValues Gradsko => EnumValues.Gradsko;

            /// <summary>
            /// Debar
            /// </summary>
            public static EnumValues Debar => EnumValues.Debar;

            /// <summary>
            /// Debarca 
            /// </summary>
            public static EnumValues Debarca => EnumValues.Debarca;

            /// <summary>
            /// Delčevo
            /// </summary>
            public static EnumValues Delčevo => EnumValues.Delčevo;

            /// <summary>
            /// Demir Kapija 
            /// </summary>
            public static EnumValues DemirKapija => EnumValues.DemirKapija;

            /// <summary>
            /// Demir Hisar
            /// </summary>
            public static EnumValues DemirHisar => EnumValues.DemirHisar;

            /// <summary>
            /// Dojran 
            /// </summary>
            public static EnumValues Dojran => EnumValues.Dojran;

            /// <summary>
            /// Dolneni
            /// </summary>
            public static EnumValues Dolneni => EnumValues.Dolneni;

            /// <summary>
            /// Želino 
            /// </summary>
            public static EnumValues Želino => EnumValues.Želino;

            /// <summary>
            /// Zelenikovo
            /// </summary>
            public static EnumValues Zelenikovo => EnumValues.Zelenikovo;

            /// <summary>
            /// Zrnovci
            /// </summary>
            public static EnumValues Zrnovci => EnumValues.Zrnovci;

            /// <summary>
            /// Ilinden 
            /// </summary>
            public static EnumValues Ilinden => EnumValues.Ilinden;

            /// <summary>
            /// Jegunovce
            /// </summary>
            public static EnumValues Jegunovce => EnumValues.Jegunovce;

            /// <summary>
            /// Kavadarci 
            /// </summary>
            public static EnumValues Kavadarci => EnumValues.Kavadarci;

            /// <summary>
            /// Karbinci 
            /// </summary>
            public static EnumValues Karbinci => EnumValues.Karbinci;

            /// <summary>
            /// Kičevo
            /// </summary>
            public static EnumValues Kičevo => EnumValues.Kičevo;

            /// <summary>
            /// Konče 
            /// </summary>
            public static EnumValues Konče => EnumValues.Konče;

            /// <summary>
            /// Kočani
            /// </summary>
            public static EnumValues Kočani => EnumValues.Kočani;

            /// <summary>
            /// Kratovo
            /// </summary>
            public static EnumValues Kratovo => EnumValues.Kratovo;

            /// <summary>
            /// Kriva Palanka
            /// </summary>
            public static EnumValues KrivaPalanka => EnumValues.KrivaPalanka;

            /// <summary>
            /// Krivogaštani
            /// </summary>
            public static EnumValues Krivogaštani => EnumValues.Krivogaštani;

            /// <summary>
            /// Kruševo
            /// </summary>
            public static EnumValues Kruševo => EnumValues.Kruševo;


            /// <summary>
            /// Kumanovo
            /// </summary>
            public static EnumValues Kumanovo => EnumValues.Kumanovo;

            /// <summary>
            /// Lipkovo
            /// </summary>
            public static EnumValues Lipkovo => EnumValues.Lipkovo;

            /// <summary>
            /// Lozovo
            /// </summary>
            public static EnumValues Lozovo => EnumValues.Lozovo;

            /// <summary>
            /// Mavrovo and Rostuša
            /// </summary>
            public static EnumValues MavrovoAndRostuša => EnumValues.MavrovoAndRostuša;

            /// <summary>
            /// Makedonska Kamenica
            /// </summary>
            public static EnumValues MakedonskaKamenica => EnumValues.MakedonskaKamenica;

            /// <summary>
            /// Makedonski Brod
            /// </summary>
            public static EnumValues MakedonskiBrod => EnumValues.MakedonskiBrod;

            /// <summary>
            /// Mogila
            /// </summary>
            public static EnumValues Mogila => EnumValues.Mogila;

            /// <summary>
            /// Negotino
            /// </summary>
            public static EnumValues Negotino => EnumValues.Negotino;

            /// <summary>
            /// Novaci
            /// </summary>
            public static EnumValues Novaci => EnumValues.Novaci;

            /// <summary>
            /// Novo Selo
            /// </summary>
            public static EnumValues NovoSelo => EnumValues.NovoSelo;

            /// <summary>
            /// Ohrid
            /// </summary>
            public static EnumValues Ohrid => EnumValues.Ohrid;

            /// <summary>
            /// Petrovec
            /// </summary>
            public static EnumValues Petrovec => EnumValues.Petrovec;

            /// <summary>
            /// Pehčevo
            /// </summary>
            public static EnumValues Pehčevo => EnumValues.Pehčevo;

            /// <summary>
            /// Plasnica
            /// </summary>
            public static EnumValues Plasnica => EnumValues.Plasnica;

            /// <summary>
            /// Prilep
            /// </summary>
            public static EnumValues Prilep => EnumValues.Prilep;

            /// <summary>
            /// Probištip
            /// </summary>
            public static EnumValues Probištip => EnumValues.Probištip;

            /// <summary>
            /// Radoviš
            /// </summary>
            public static EnumValues Radoviš => EnumValues.Radoviš;

            /// <summary>
            /// Rankovce
            /// </summary>
            public static EnumValues Rankovce => EnumValues.Rankovce;

            /// <summary>
            /// Resen
            /// </summary>
            public static EnumValues Resen => EnumValues.Resen;

            /// <summary>
            /// Rosoman
            /// </summary>
            public static EnumValues Rosoman => EnumValues.Rosoman;

            /// <summary>
            /// Sveti Nikole
            /// </summary>
            public static EnumValues SvetiNikole => EnumValues.SvetiNikole;

            /// <summary>
            /// Sopište
            /// </summary>
            public static EnumValues Sopište => EnumValues.Sopište;

            /// <summary>
            /// Staro Nagoričane
            /// </summary>
            public static EnumValues StaroNagoričane => EnumValues.StaroNagoričane;

            /// <summary>
            /// Struga
            /// </summary>
            public static EnumValues Struga => EnumValues.Struga;

            /// <summary>
            /// Strumica
            /// </summary>
            public static EnumValues Strumica => EnumValues.Strumica;

            /// <summary>
            /// Studeničani
            /// </summary>
            public static EnumValues Studeničani => EnumValues.Studeničani;

            /// <summary>
            /// Tearce
            /// </summary>
            public static EnumValues Tearce => EnumValues.Tearce;

            /// <summary>
            /// Hautes-Pyrénées
            /// </summary>
            public static EnumValues Tetovo => EnumValues.Tetovo;

            /// <summary>
            /// Centar Župa
            /// </summary>
            public static EnumValues CentarŽupa => EnumValues.CentarŽupa;

            /// <summary>
            /// Čaška
            /// </summary>
            public static EnumValues Čaška => EnumValues.Čaška;

            /// <summary>
            /// Češinovo-Obleševo
            /// </summary>
            public static EnumValues ČešinovoObleševo => EnumValues.ČešinovoObleševo;

            /// <summary>
            /// Čučer-Sandevo
            /// </summary>
            public static EnumValues ČučerSandevo => EnumValues.ČučerSandevo;

            /// <summary>
            /// Štip
            /// </summary>
            public static EnumValues Štip => EnumValues.Štip;

            /// <summary>
            /// Skopje
            /// </summary>
            public static EnumValues Skopje => EnumValues.Skopje;
        }

        #endregion

        #region Region definition

        /// <summary>
        /// Enum values for Macedonia regions.
        /// </summary>
        public enum EnumValues
        {
            /// <summary>
            /// Aračinovo
            /// </summary>
            [AliasInShort("02")]
            [RegionCode(2_00_125_0002)]
            Aračinovo,

            /// <summary>
            /// Berovo
            /// </summary>
            [AliasInShort("03")]
            [RegionCode(2_00_125_0003)]
            Berovo,

            /// <summary>
            /// Bitola
            /// </summary>
            [AliasInShort("04")]
            [RegionCode(2_00_125_0004)]
            Bitola,

            /// <summary>
            /// Bogdanci
            /// </summary>
            [AliasInShort("05")]
            [RegionCode(2_00_125_0005)]
            Bogdanci,

            /// <summary>
            /// Bogovinje
            /// </summary>
            [AliasInShort("06")]
            [RegionCode(2_00_125_0006)]
            Bogovinje,

            /// <summary>
            /// Bosilovo
            /// </summary>
            [AliasInShort("07")]
            [RegionCode(2_00_125_0007)]
            Bosilovo,

            /// <summary>
            /// Brvenica
            /// </summary>
            [AliasInShort("08")]
            [RegionCode(2_00_125_0008)]
            Brvenica,

            /// <summary>
            /// Valandovo
            /// </summary>
            [AliasInShort("10")]
            [RegionCode(2_00_125_0010)]
            Valandovo,

            /// <summary>
            /// Vasilevo
            /// </summary>
            [AliasInShort("11")]
            [RegionCode(2_00_125_0011)]
            Vasilevo,

            /// <summary>
            /// Vevčani
            /// </summary>
            [AliasInShort("12")]
            [RegionCode(2_00_125_0012)]
            Vevčani,

            /// <summary>
            /// Veles
            /// </summary>
            [AliasInShort("13")]
            [RegionCode(2_00_125_0013)]
            Veles,

            /// <summary>
            /// Vinica
            /// </summary>
            [AliasInShort("14")]
            [RegionCode(2_00_125_0014)]
            Vinica,

            /// <summary>
            /// Vrapčište
            /// </summary>
            [AliasInShort("16")]
            [RegionCode(2_00_125_0016)]
            Vrapčište,

            /// <summary>
            /// Gevgelija
            /// </summary>
            [AliasInShort("18")]
            [RegionCode(2_00_125_0018)]
            Gevgelija,

            /// <summary>
            /// Gostivar
            /// </summary>
            [AliasInShort("19")]
            [RegionCode(2_00_125_0019)]
            Gostivar,

            /// <summary>
            /// Gradsko
            /// </summary>
            [AliasInShort("20")]
            [RegionCode(2_00_125_0020)]
            Gradsko,

            /// <summary>
            /// Debar
            /// </summary>
            [AliasInShort("21")]
            [RegionCode(2_00_125_0021)]
            Debar,

            /// <summary>
            /// Debarca
            /// </summary>
            [AliasInShort("22")]
            [RegionCode(2_00_125_0022)]
            Debarca,

            /// <summary>
            /// Delčevo
            /// </summary>
            [AliasInShort("23")]
            [RegionCode(2_00_125_0023)]
            Delčevo,

            /// <summary>
            /// Demir Kapija
            /// </summary>
            [AliasInShort("24")]
            [RegionCode(2_00_125_0024)]
            DemirKapija,

            /// <summary>
            /// Demir Hisar
            /// </summary>
            [AliasInShort("25")]
            [RegionCode(2_00_125_0025)]
            DemirHisar,

            /// <summary>
            /// Dojran
            /// </summary>
            [AliasInShort("26")]
            [RegionCode(2_00_125_0026)]
            Dojran,

            /// <summary>
            /// Dolneni
            /// </summary>
            [AliasInShort("27")]
            [RegionCode(2_00_125_0027)]
            Dolneni,

            /// <summary>
            /// Želino
            /// </summary>
            [AliasInShort("30")]
            [RegionCode(2_00_125_0030)]
            Želino,

            /// <summary>
            /// Zelenikovo
            /// </summary>
            [AliasInShort("32")]
            [RegionCode(2_00_125_0032)]
            Zelenikovo,

            /// <summary>
            /// Zrnovci
            /// </summary>
            [AliasInShort("33")]
            [RegionCode(2_00_125_0033)]
            Zrnovci,

            /// <summary>
            /// Ilinden
            /// </summary>
            [AliasInShort("34")]
            [RegionCode(2_00_125_0034)]
            Ilinden,

            /// <summary>
            /// Jegunovce
            /// </summary>
            [AliasInShort("35")]
            [RegionCode(2_00_125_0035)]
            Jegunovce,

            /// <summary>
            /// Kavadarci
            /// </summary>
            [AliasInShort("36")]
            [RegionCode(2_00_125_0036)]
            Kavadarci,

            /// <summary>
            /// Karbinci
            /// </summary>
            [AliasInShort("37")]
            [RegionCode(2_00_125_0037)]
            Karbinci,

            /// <summary>
            /// Kičevo
            /// </summary>
            [AliasInShort("40")]
            [RegionCode(2_00_125_0040)]
            Kičevo,

            /// <summary>
            /// Konče
            /// </summary>
            [AliasInShort("41")]
            [RegionCode(2_00_125_0041)]
            Konče,

            /// <summary>
            /// Kočani
            /// </summary>
            [AliasInShort("42")]
            [RegionCode(2_00_125_0042)]
            Kočani,

            /// <summary>
            /// Kratovo
            /// </summary>
            [AliasInShort("43")]
            [RegionCode(2_00_125_0043)]
            Kratovo,

            /// <summary>
            /// Kriva Palanka
            /// </summary>
            [AliasInShort("44")]
            [RegionCode(2_00_125_0044)]
            KrivaPalanka,

            /// <summary>
            /// Krivogaštani
            /// </summary>
            [AliasInShort("45")]
            [RegionCode(2_00_125_0045)]
            Krivogaštani,

            /// <summary>
            /// Kruševo
            /// </summary>
            [AliasInShort("46")]
            [RegionCode(2_00_125_0046)]
            Kruševo,

            /// <summary>
            /// Kumanovo
            /// </summary>
            [AliasInShort("47")]
            [RegionCode(2_00_125_0047)]
            Kumanovo,

            /// <summary>
            /// Lipkovo
            /// </summary>
            [AliasInShort("48")]
            [RegionCode(2_00_125_0048)]
            Lipkovo,

            /// <summary>
            /// Lozovo
            /// </summary>
            [AliasInShort("49")]
            [RegionCode(2_00_125_0049)]
            Lozovo,

            /// <summary>
            /// Mavrovo and Rostuša
            /// </summary>
            [AliasInShort("50")]
            [RegionCode(2_00_125_0050)]
            MavrovoAndRostuša,

            /// <summary>
            /// Makedonska Kamenica
            /// </summary>
            [AliasInShort("51")]
            [RegionCode(2_00_125_0051)]
            MakedonskaKamenica,

            /// <summary>
            /// Makedonski Brod
            /// </summary>
            [AliasInShort("52")]
            [RegionCode(2_00_125_0052)]
            MakedonskiBrod,

            /// <summary>
            /// Mogila
            /// </summary>
            [AliasInShort("53")]
            [RegionCode(2_00_125_0053)]
            Mogila,

            /// <summary>
            /// Negotino
            /// </summary>
            [AliasInShort("54")]
            [RegionCode(2_00_125_0054)]
            Negotino,

            /// <summary>
            /// Novaci
            /// </summary>
            [AliasInShort("55")]
            [RegionCode(2_00_125_0055)]
            Novaci,

            /// <summary>
            /// Novo Selo
            /// </summary>
            [AliasInShort("56")]
            [RegionCode(2_00_125_0056)]
            NovoSelo,

            /// <summary>
            /// Ohrid
            /// </summary>
            [AliasInShort("58")]
            [RegionCode(2_00_125_0058)]
            Ohrid,

            /// <summary>
            /// Petrovec
            /// </summary>
            [AliasInShort("59")]
            [RegionCode(2_00_125_0059)]
            Petrovec,

            /// <summary>
            /// Pehčevo
            /// </summary>
            [AliasInShort("60")]
            [RegionCode(2_00_125_0060)]
            Pehčevo,

            /// <summary>
            /// Plasnica
            /// </summary>
            [AliasInShort("61")]
            [RegionCode(2_00_125_0061)]
            Plasnica,

            /// <summary>
            /// Prilep
            /// </summary>
            [AliasInShort("62")]
            [RegionCode(2_00_125_0062)]
            Prilep,

            /// <summary>
            /// 
            /// </summary>
            [AliasInShort("63")]
            [RegionCode(2_00_125_0063)]
            Probištip,

            /// <summary>
            /// Radoviš
            /// </summary>
            [AliasInShort("64")]
            [RegionCode(2_00_125_0064)]
            Radoviš,

            /// <summary>
            /// Rankovce
            /// </summary>
            [AliasInShort("65")]
            [RegionCode(2_00_125_0065)]
            Rankovce,

            /// <summary>
            /// Resen
            /// </summary>
            [AliasInShort("66")]
            [RegionCode(2_00_125_0066)]
            Resen,

            /// <summary>
            /// Rosoman
            /// </summary>
            [AliasInShort("67")]
            [RegionCode(2_00_125_0067)]
            Rosoman,

            /// <summary>
            /// Sveti Nikole
            /// </summary>
            [AliasInShort("69")]
            [RegionCode(2_00_125_0069)]
            SvetiNikole,

            /// <summary>
            /// Sopište
            /// </summary>
            [AliasInShort("70")]
            [RegionCode(2_00_125_0070)]
            Sopište,

            /// <summary>
            /// Staro Nagoričane
            /// </summary>
            [AliasInShort("71")]
            [RegionCode(2_00_125_0071)]
            StaroNagoričane,

            /// <summary>
            /// Struga
            /// </summary>
            [AliasInShort("72")]
            [RegionCode(2_00_125_0072)]
            Struga,

            /// <summary>
            /// Strumica
            /// </summary>
            [AliasInShort("73")]
            [RegionCode(2_00_125_0073)]
            Strumica,

            /// <summary>
            /// Studeničani
            /// </summary>
            [AliasInShort("74")]
            [RegionCode(2_00_125_0074)]
            Studeničani,

            /// <summary>
            /// Tearce
            /// </summary>
            [AliasInShort("75")]
            [RegionCode(2_00_125_0075)]
            Tearce,

            /// <summary>
            /// Tetovo
            /// </summary>
            [AliasInShort("76")]
            [RegionCode(2_00_125_0076)]
            Tetovo,

            /// <summary>
            /// Centar Župa
            /// </summary>
            [AliasInShort("78")]
            [RegionCode(2_00_125_0078)]
            CentarŽupa,

            /// <summary>
            /// Čaška
            /// </summary>
            [AliasInShort("80")]
            [RegionCode(2_00_125_0080)]
            Čaška,

            /// <summary>
            /// Češinovo-Obleševo
            /// </summary>
            [AliasInShort("81")]
            [RegionCode(2_00_125_0081)]
            ČešinovoObleševo,

            /// <summary>
            /// Čučer-Sandevo
            /// </summary>
            [AliasInShort("82")]
            [RegionCode(2_00_125_0082)]
            ČučerSandevo,

            /// <summary>
            /// Štip
            /// </summary>
            [AliasInShort("83")]
            [RegionCode(2_00_125_0083)]
            Štip,

            /// <summary>
            /// Skopje
            /// </summary>
            [AliasInShort("85")]
            [RegionCode(2_00_125_0085)]
            Skopje,

            /// <summary>
            /// Unknown
            /// </summary>
            [IgnoreRegion]
            [AliasInShort("??")]
            [RegionCode(0)]
            Unknown,
        }

        #endregion

        #region All regions getter

        /// <summary>
        /// Get all region code
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<string> GetAllRegionCodes()
            => InternalEnumMembersCache.Select(member => member.Value.ToFullRegionCode());

        /// <summary>
        /// Get all numeric region code(CEP-1 / Cosmos Region Code).
        /// </summary>
        /// <returns></returns>
        public static IEnumerable<long> GetAllNumericRegionCodes()
            => InternalEnumMembersCache.Select(member => member.Value.ToNumericRegionCode());

        #endregion
    }
}